﻿//-----------------------------------------------------------------------
// <copyright file="Projects.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.ViewModels
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.LiveTile;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.Models;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.MVVMSupport;
    using Windows.ApplicationModel.DataTransfer;
    using Windows.Storage.Streams;
    using Windows.UI.StartScreen;

    /// <summary>
    /// The view model for the projects page.
    /// </summary>
    public class Projects : IShare, INotifyPropertyChanged
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Projects"/> class.
        /// </summary>
        /// <param name="category">The category.</param>
        public Projects(int category)
        {
            this.Category = category;
            DataTransferManager.GetForCurrentView().DataRequested += this.Project_DataRequested;
            var selectedCategory = (from c in App.Database.Categories
                                    where c.Id == category
                                    select c).Single();

            this.ProjectCollection = selectedCategory.Projects;

            this.GoBack = new Command(Navigation.GoBack);

            this.GoToHome = new Command(() => Navigation.Navigate(typeof(Views.TreasureMapPage)));

            this.MarkGuidanceAsDone = new Command<Models.Guidance>(guidanceItem =>
                {
                    App.Database.StatusManager.SetStatus(guidanceItem.Id, Models.Status.Completed);
                    TileGenerator.GeneratePercentageTile();
                });

            this.PinProject = new Command(this.PinProjectTile);

            this.ToggleFavourite = new Command(() =>
            {
                Models.Favourites.ToggleFavourite(this.SelectedProject.Id, FavouriteType.Project);
                RaisePropertyChanged("IsFavourite");
            });

            this.LaunchSearch = new Command(() => Windows.ApplicationModel.Search.SearchPane.GetForCurrentView().Show());
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Projects"/> class.
        /// </summary>
        /// <param name="values">The values.</param>
        public Projects(Tuple<int, Models.Project> values)
            : this(values.Item1)
        {
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            this.SelectedProject = values.Item2;
        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the launch search.
        /// </summary>
        /// <value>The launch search.</value>
        public Command LaunchSearch { get; set; }

        /// <summary>
        /// Gets or sets the Category of a project.
        /// </summary>
        /// <value>The category.</value>
        public int Category { get; set; }

        /// <summary>
        /// Gets the go back command.
        /// </summary>
        /// <value>The go back.</value>
        public Command GoBack { get; private set; }

        /// <summary>
        /// Gets the command for the home button
        /// </summary>
        /// <value>The go to home.</value>
        public Command GoToHome { get; private set; }

        /// <summary>
        /// Gets a value indicating whether this instance is favourite.
        /// </summary>
        /// <value><c>true</c> if this instance is favourite; otherwise, <c>false</c>.</value>
        public bool IsFavourite
        {
            get
            {
                return Models.Favourites.IsFavourite(this.SelectedProject.Id, FavouriteType.Project);
            }
        }

        /// <summary>
        /// Gets the mark guidance as done.
        /// </summary>
        /// <value>The mark guidance as done.</value>
        public Command<Models.Guidance> MarkGuidanceAsDone { get; private set; }

        /// <summary>
        /// Gets the pin project.
        /// </summary>
        /// <value>The pin project.</value>
        public Command PinProject { get; private set; }

        /// <summary>
        /// Gets or sets the collection of projects associated with this project.
        /// </summary>
        /// <value>The project collection.</value>
        public Models.Project[] ProjectCollection { get; set; }

        /// <summary>
        /// Gets or sets the currently selected project.
        /// </summary>
        /// <value>The selected project.</value>
        public Models.Project SelectedProject { get; set; }

        /// <summary>
        /// Gets the toggle favourite.
        /// </summary>
        /// <value>The toggle favourite.</value>
        public Command ToggleFavourite { get; private set; }

        /// <summary>
        /// De-registers the share handler
        /// </summary>
        public void Unregister()
        {
            DataTransferManager.GetForCurrentView().DataRequested -= this.Project_DataRequested;
        }

        /// <summary>
        /// Share request handler.
        /// </summary>
        /// <param name="sender">This parameter is not used.</param>
        /// <param name="args">This parameter is not used.</param>
        public void Project_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            // For twitter sharing
            var projectName = this.SelectedProject.Name + Environment.NewLine;
            var content = string.Empty;

            foreach (var item in this.SelectedProject.Guidance)
            {
                content += string.Format(CultureInfo.InvariantCulture, "{0}: {1}{2}", item.GuidanceType, item.Url, Environment.NewLine);
            }

            var titleMaxLength = 140 - content.Length;
            if (titleMaxLength < projectName.Length)
            {
                projectName = projectName.Substring(0, titleMaxLength) + "..." + Environment.NewLine;
            }

            content = projectName + content;
            args.Request.Data.SetText(content);

            // For email sharing
            args.Request.Data.Properties.Title = "ALM Readiness Treasure Map";
            args.Request.Data.Properties.Description = "Treasure from the " + this.SelectedProject.Name;

            var htmlExample = string.Format(CultureInfo.InvariantCulture, "<h1>{0}</h1><br>{1}<br><img src='{2}'></img>", this.SelectedProject.Name, this.SelectedProject.Description, "Image.png");

            foreach (var item in this.SelectedProject.Guidance)
            {
                htmlExample += string.Format(CultureInfo.InvariantCulture, "<p>{0}: {1}</p>", item.GuidanceType, item.Url);
            }

            args.Request.Data.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat(htmlExample));

            // Because the HTML contains a local image, we need to add it to the ResourceMap.
            var streamRef = RandomAccessStreamReference.CreateFromUri(new Uri(this.SelectedProject.Image));
            args.Request.Data.ResourceMap["Image.png"] = streamRef;
        }

        /// <summary>
        /// Pins the project tile.
        /// </summary>
        private async void PinProjectTile()
        {
            var id = string.Format("project-{0}", this.SelectedProject.Id);
            var logo = new Uri(this.SelectedProject.Image.Replace(".png", "-small.png"));
            var tile = new SecondaryTile(id, this.SelectedProject.Name, this.SelectedProject.Name, id, TileOptions.ShowNameOnLogo, logo);
            await tile.RequestCreateAsync();
        }

        /// <summary>
        /// Raises the property changed.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        private void RaisePropertyChanged(string propertyName = "")
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}